#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
#include <sstream>
#include <memory>
#include <sstream>

// 封装序列化 -- StreamWriter
bool serialize(const Json::Value &val, std::string &str)
{
    // 通过工厂对象去创建StreamWriter
    Json::StreamWriterBuilder swb;
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    // 序列化 -- val对象 + 输出流
    std::stringstream ss;
    int ret = sw->write(val, &ss);
    if (ret != 0)
    {
        std::cout << " Json serialize fail " << std::endl;
        return false;
    }
    // 把结果写回去
    str = ss.str();
    return true;
}

// 封装反序列化 -- CharReader
bool deserialize(const std::string &str, Json::Value &val)
{
    // 通过工厂对象去创建StreamWriter
    Json::CharReaderBuilder crb;
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    // 反序列化 -- 字符串 + val对象
    // 告诉字符串的起始位置, 结束位置, 写进那个val对象, 错误返回
    std::string err;
    bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), &val, &err);
    if (ret == false)
    {
        std::cout << " Json deserialize fail " << err << std::endl;
        return false;
    }
    return true;
}

int main()
{
    // 1.测试序列化
    std::string name = "张三";
    std::string sex = "男";
    int age = 19;
    float score[3] = {88, 89, 90};
    Json::Value student;
    student["姓名"] = name;
    student["性别"] = sex;
    student["年龄"] = age;
    student["成绩"].append(score[0]);
    student["成绩"].append(score[1]);
    student["成绩"].append(score[2]);
    Json::Value fav;
    fav["书籍"] = "西游记";
    fav["运动"] = "羽毛球";
    student["爱好"] = fav;

    std::string ret;
    serialize(student, ret);
    std::cout << "序列化的结果" << std::endl
              << ret << std::endl;

    // 2.测试反序列化
    Json::Value stu2;
    deserialize(ret, stu2);
    std::cout << "反序列化的结果" << std::endl
              << stu2["姓名"].asCString() << std::endl
              << stu2["性别"].asCString() << std::endl
              << stu2["年龄"].asInt() << std::endl
              << stu2["成绩"][0].asInt() << std::endl
              << stu2["成绩"][1].asInt() << std::endl
              << stu2["成绩"][2].asInt() << std::endl;

    return 0;
}

// // 实现数据的序列化 -- 核心是Value对象 + 输出流
// void serialize() {
//     std::string name = "张三";
//     std::string sex = "男";
//     int age = 19;
//     float score[3] = {88, 89, 90};

//     Json::Value student;
//     student["姓名"] = name;
//     student["性别"] = sex;
//     student["年龄"] = age;
//     student["成绩"].append(score[0]);
//     student["成绩"].append(score[1]);
//     student["成绩"].append(score[2]);

//     // 再嵌套json
//     Json::Value fav;
//     fav["书籍"] = "西游记";
//     fav["运动"] = "羽毛球";
//     student["爱好"] = fav;

//     // 通过工厂对象去创建StreamWriter
//     Json::StreamWriterBuilder swb;
//     std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
//     // 序列化 -- val对象 + 输出流
//     sw->write(student, &std::cout);
//     std::cout << std::endl;
// }